<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<img src="images/8-3-原型.jpg" style="width: 500px" />
<script>
    /*
        0.  2个方法
            Object.values()
            Object.entries()
     */

    // 0.1.举例
    const symbol = Symbol('foo')
    const obj = {
        name: '张三',
        age: 13,
        friend: {},
        [symbol]: 'foo'
    }

    // symbol属性会被忽略
    console.log(Object.values((obj)))
    console.log(Object.entries(obj))
    console.log('------')

    /*
        1.其他原型语法
     */
    // 1.1 这样写,没有了constructor
    function Person1() {
    }

    Person1.prototype = {
        name: 'jack',
        age: 23,
        job: 'boss',
        sayName() {
            console.log(this.name)
        }
    }
    let friend = new Person1();
    console.log(friend, friend.sayName())
    console.log('------')


    // 1.2 手动关联constructor
    function Person2() {
    }

    Person2.prototype = {
        constructor: Person2,
        name: 'jack',
        age: 23,
        job: 'boss',
        sayName() {
            console.log('this', this)
            console.log(this.name)
        }
    }
    let person2 = new Person2();
    // constructor属性默认是不可枚举的,但是这样变成可以枚举的了
    person2.sayName() // this
    console.log('person2', person2)
    console.log('------')


    // 1.3 所以需要改为不可枚举
    Object.defineProperty(Person2.prototype, 'constructor', {
        enumerable: false,
        value: Person2
    })
    console.log(person2, person2.sayName(), Person2.prototype.sayName())
    console.log('------')

    /*
        2.原型的动态性
     */
    // 2.1  可以访问
    function Person2_1() {
    }

    let friend2_1 = new Person2_1();
    Person2_1.prototype.sayHi = function () {
        console.log('hi')
    }
    // 2.2  不能访问
    console.log('---2.2---')

    function Person2_2() {
    }
    let friend2_2 = new Person2_2();    //  在这里new的时候,下面的friend2_2.sayName()会报错
    Person2_2.prototype = {
        name:'张三',
        sayName(){
            console.log(this.name())
        }
    }
    console.log(friend2_2)
    // friend2_2.sayName()  // 报错
    // 原因 看图8-3-原型
    
    /*
        3.原生对象原型
            - 比如Array.prototype.sort
            - 比如String.prototype.substring
            这些方法都是定义在原型上的,所以可以直接用
            String.prototype.startsWith = function(){}修改
            //但是不推荐这么做,推荐定义一个类继承原生类型
     */
    
    /*
        4.  原型的问题
            - 使用引用值的问题
     */
</script>
</body>
</html>